home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / RUNTIME.ZIP / OCAT.R < prev    next >
Encoding:
Text File  |  1992-02-10  |  3.1 KB  |  121 lines

  1. /*
  2.  * File: ocat.r -- caterr, lconcat
  3.  */
  4. "x || y - concatenate strings x and y." 
  5.  
  6. operator{1} || cater(x, y)
  7.  
  8.    if !cnv:string(x) then
  9.       runerr(103, x)
  10.    if !cnv:string(y) then
  11.       runerr(103, y)
  12.  
  13.    abstract {
  14.       return string
  15.       }
  16.  
  17.    body {
  18.       /*
  19.        *  Optimization 1:  The strings to be concatenated are already
  20.        *   adjacent in memory; no allocation is required.
  21.        */
  22.       if (StrLoc(x) + StrLen(x) == StrLoc(y)) {
  23.          StrLoc(result) = StrLoc(x);
  24.          StrLen(result) = StrLen(x) + StrLen(y);
  25.          return result;
  26.          }
  27. #ifdef MultiRegion
  28.       else if ((StrLoc(x) + StrLen(x) == strfree) && (DiffPtrs(strend,strfree) > StrLen(y))) {
  29. #else                    /* MultiRegion */
  30.       else if (StrLoc(x) + StrLen(x) == strfree) {
  31. #endif                    /* MultiRegion */
  32.          /*
  33.           * Optimization 2: The end of x is at the end of the string space.
  34.           *  Hence, x was the last string allocated and need not be
  35.           *  re-allocated. y is appended to the string space and the
  36.           *  result is pointed to the start of x.
  37.           */
  38.      result = x;
  39.          }
  40.       else {
  41.          /*
  42.           * Otherwise, append x to the end of the string space and
  43.           *  point the result to the start of y.
  44.           */
  45.          Protect(StrLoc(result) = alcstr(StrLoc(x),StrLen(x)), runerr(0));
  46.          StrLen(result) = StrLen(x);
  47.          }
  48.  
  49.       /*
  50.        * Append y to the end of the string space.
  51.        */
  52.       Protect(alcstr(StrLoc(y),StrLen(y)), runerr(0));
  53.       /*
  54.        *  Set the length of the result and return.
  55.        */
  56.       StrLen(result) = StrLen(x) + StrLen(y);
  57.       return result;
  58.       }
  59. end
  60.  
  61.  
  62. "x ||| y - concatenate lists x and y."
  63.  
  64. operator{1} ||| lconcat(x, y)
  65.    /*
  66.     * x and y must be lists.
  67.     */
  68.    if !is:list(x) then
  69.       runerr(108, x)
  70.    if !is:list(y) then
  71.       runerr(108, y)
  72.  
  73.    abstract {
  74.       return new list(store[(type(x) ++ type(y)).lst_elem])
  75.       }
  76.  
  77.    body {
  78.       register struct b_list *bp1, *bp2;
  79.       register struct b_lelem *lp1, *lp2;
  80.       word size1, size2;
  81.  
  82.       /*
  83.        * Get the size of both lists.
  84.        */
  85.       size1 = BlkLoc(x)->list.size;
  86.       size2 = BlkLoc(y)->list.size;
  87.  
  88.       /*
  89.        * Make a copy of both lists.
  90.        */
  91.       if (cplist(&x, &x, (word)1, size1 + 1) == Error)
  92.          runerr(0);
  93.       if (cplist(&y, &y, (word)1, size2 + 1) == Error)
  94.          runerr(0);
  95.  
  96.       /*
  97.        * Get a pointer to both lists.  bp1 points to the copy of x
  98.        *  and is the list that will be returned.
  99.        */
  100.       bp1 = (struct b_list *) BlkLoc(x);
  101.       bp2 = (struct b_list *) BlkLoc(y);
  102.  
  103.       /*
  104.        * Perform the concatenation by hooking the lists together.
  105.        */
  106.       lp1 = (struct b_lelem *) bp1->listtail;
  107.       lp2 = (struct b_lelem *) bp2->listhead;
  108.  
  109.       lp1->listnext = (union block *) lp2;
  110.       lp2->listprev = (union block *) lp1;
  111.  
  112.       /*
  113.        * Adjust the size field to reflect the length of the concatenated lists.
  114.        */
  115.       bp1->size = size1 + size2;
  116.       bp1->listtail = bp2->listtail;
  117.  
  118.       return x;
  119.       }
  120. end
  121.